<template>
  <form class="gems-form" >
    <slot />
  </form>
</template>


<script setup lang="ts">
import { provide } from 'vue'
import type { ValidateFieldsError, } from 'async-validator'
import type { FormProps, FormItemContext, FormContext, FormInstance, FormValidateFailure } from './types'
import { formContextKey } from './types'

defineOptions({
  name: 'GemsForm',
})
const props = defineProps<FormProps>()

// 存放表单项的上下文
const fields: FormItemContext[] = []
// 将item添加到fields中
const addField: FormContext['addField'] = (field: FormItemContext) => {
  fields.push(field)
}
// 从fields中移除item
const removeField: FormContext['removeField'] = (field: FormItemContext) => {
  if (field.prop) {
    const index = fields.findIndex((item) => item.prop === field.prop)
    if (index > -1) {
      fields.splice(index, 1)
    }
  }
}
// 重置空完整表单信息--keys表示需要重置的字段
const resetFields: FormContext['resetFields'] = (keys = []) => {
  const filterArr = keys.length > 0 ? fields.filter(field => keys.includes(field.prop)) : fields
  filterArr.forEach(field => field.resetField())
}
// 清空完整表单验证信息--keys表示需要清除的字段
const clearValidate: FormContext['clearValidate'] = (keys = []) => {
  const filterArr = keys.length > 0 ? fields.filter(field => keys.includes(field.prop)) : fields
  filterArr.forEach(field => field.clearValidate())
}
// 完整表单校验
const validate = async () => {
  let validateFieldsError: ValidateFieldsError = {}
  for (const field of fields) {
    try {
      await field.validate('')
    } catch (e) {
      const error = e as FormValidateFailure
      validateFieldsError = {
        ...validateFieldsError,
        ...error.fields
      }
    }
  }
  if (Object.keys(validateFieldsError).length > 0) {
    return Promise.reject(validateFieldsError)
  } else {
    return true
  }
}

// 向子组件提供上下文
provide(formContextKey, {
  ...props,
  addField,
  removeField,
  resetFields,
  clearValidate,
  validate
})

defineExpose<FormInstance>({
  validate,
  resetFields,
  clearValidate,
})

</script>